package com.yu.service;

import cn.hutool.core.util.IdUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;


@Service
public class PaymentService {
    /**
     * 正常访问，肯定正确的方法
     * @param id
     * @return
     */
    public String paymentInfo_OK(Integer id){
        return "线程池:"+ Thread.currentThread().getName() + "PaymentInfo_OK,id:"+id+"\t"+"O(∩_∩)O哈哈~";
    }
    //这个注解的意思就是降级，如果该方法出现问题，就去调用paymentInfo_TimeOutHandler()方法
    //下面那个注解就是，调用时间为三秒，超过了就降级，
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")
    })
    public String paymentInfo_TimeOut(Integer id){
        //模拟成一个复杂的业务，让他运行3秒
        int numTime = 3; //出现了超时
        //int age = 10/0;  //出现了异常
        //都会进行服务降级，走到下面兜底的方法
        try {
            Thread.sleep(numTime*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "线程池:"+ Thread.currentThread().getName() +"id:"+id+"\t"+"O(∩_∩)O哈哈~" + "耗时:"+numTime+"秒";
    }


    public String paymentInfo_TimeOutHandler(Integer id){
        return "线程池:"+ Thread.currentThread().getName() + "paymentInfo_TimeOutHandler,id:"+id+"\n"+"8001系统繁忙，请稍后重试 o(╥﹏╥)o";
    }


    // 下面是服务熔断
    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),//开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),//配置请求个数 当在配置时间窗口内达到此数量的失败后，进行短路。默认20个）
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//时间窗口期，当熔断十秒后，开始尝试恢复，默认5s
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60")//出错百分比阈值，当达到此阈值后，开始短路。默认50%
    })
    public String paymentCircuitBreaker(@PathVariable("id") Integer id){
        if (id<0)
            throw new RuntimeException("id不能为负数");
        String serialNumber = IdUtil.simpleUUID();
        return Thread.currentThread().getName()+"\t"+"success"+serialNumber;

    }

    public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
        return "id 不能负数，请稍后再试， id:"+id;
    }

}
